﻿using System;
using System.Collections.Generic;

namespace ProgettoWlanService
{
    /// <summary>
    /// Descrizione di riepilogo per Wifi
    /// </summary>
    public class Wifi
    {
        private const int WLAN_API_VERSION_2_0 = 2; // Windows Vista WiFi API Version
        private const int ERROR_SUCCESS = 0;

        public Wifi()
        {
            //
            // TODO: aggiungere qui la logica del costruttore
            //
        }

        /// <summary>
        /// Prints on the standard output info about the interfaces in the laptop
        /// </summary>
        public static Dictionary<string, string> getInterfaces() {

            // Dictionary<NICname, status>
            Dictionary<string, string> names = new Dictionary<string, string>();

            uint serviceVersion = 0;
            IntPtr handle = IntPtr.Zero;
            if (P_Invoke.WlanOpenHandle(WLAN_API_VERSION_2_0, IntPtr.Zero, out serviceVersion, out handle) == ERROR_SUCCESS) {
                
                IntPtr ppInterfaceList = IntPtr.Zero;
                P_Invoke.WLAN_INTERFACE_INFO_LIST interfaceList;

                if (P_Invoke.WlanEnumInterfaces(handle, IntPtr.Zero, out ppInterfaceList) == ERROR_SUCCESS) {
                    
                    interfaceList = new P_Invoke.WLAN_INTERFACE_INFO_LIST(ppInterfaceList);

                    for (int i = 0; i < interfaceList.dwNumberofItems; i++) {
                        string NIC = String.Format("{0}", interfaceList.InterfaceInfo[i].strInterfaceDescription);
                        string status = String.Format("{0}", P_Invoke.getStateDescription(interfaceList.InterfaceInfo[i].isState));
                        names.Add(NIC, status);
                    }

                    //frees memory
                    if (ppInterfaceList != IntPtr.Zero)
                        P_Invoke.WlanFreeMemory(ppInterfaceList);

                    //close handle
                    P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                    return names;
                }
                else {

                    //frees memory
                    if (ppInterfaceList != IntPtr.Zero)
                        P_Invoke.WlanFreeMemory(ppInterfaceList);

                    //close handle
                    P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                    return names;
                }

            }
            else
                return names;
        }

        public static Dictionary<string, UInt32> getAvailableNetworkList() {

            // Dictionary<NetworkName, signalStrength>
            Dictionary<string, UInt32> netList = new Dictionary<string, UInt32>();

            uint serviceVersion = 0;
            IntPtr handle = IntPtr.Zero;
            if (P_Invoke.WlanOpenHandle(WLAN_API_VERSION_2_0, IntPtr.Zero, out serviceVersion, out handle) == ERROR_SUCCESS) {

                IntPtr ppInterfaceList = IntPtr.Zero;
                P_Invoke.WLAN_INTERFACE_INFO_LIST interfaceList;

                if (P_Invoke.WlanEnumInterfaces(handle, IntPtr.Zero, out ppInterfaceList) == ERROR_SUCCESS) {
                    interfaceList = new P_Invoke.WLAN_INTERFACE_INFO_LIST(ppInterfaceList);

                    for (int i = 0; i < interfaceList.dwNumberofItems; i++) {
                        IntPtr ppNetworkList = IntPtr.Zero;

                        if (P_Invoke.WlanGetAvailableNetworkList(handle, ref interfaceList.InterfaceInfo[i].InterfaceGuid, 1, IntPtr.Zero, ref ppNetworkList) == ERROR_SUCCESS) {
                            
                            P_Invoke.WLAN_AVAILABLE_NETWORK_LIST networkList = new P_Invoke.WLAN_AVAILABLE_NETWORK_LIST(ppNetworkList);
                            
                            for (int j = 0; j < networkList.dwNumberOfItems; j++) {
                                string netName = networkList.Network[j].dot11Ssid.SSID;
                                UInt32 signalStrength = networkList.Network[j].wlanSignalQuality;
                                if(!netList.ContainsKey(netName))
                                    netList.Add(netName, signalStrength);
                            }

                            //frees memory
                            if (ppInterfaceList != IntPtr.Zero)
                                P_Invoke.WlanFreeMemory(ppInterfaceList);
                            if (ppNetworkList != IntPtr.Zero)
                                P_Invoke.WlanFreeMemory(ppNetworkList);

                            //close handle
                            P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                            return netList;
                        }
                        else {

                            //frees memory
                            if (ppInterfaceList != IntPtr.Zero)
                                P_Invoke.WlanFreeMemory(ppInterfaceList);
                            if (ppNetworkList != IntPtr.Zero)
                                P_Invoke.WlanFreeMemory(ppNetworkList);

                            //close handle
                            P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                            return netList;
                        }

                    }

                    //frees memory                           
                    if (ppInterfaceList != IntPtr.Zero)
                        P_Invoke.WlanFreeMemory(ppInterfaceList);

                    //close handle
                    P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                    return netList;

                }

                //frees memory
                if (ppInterfaceList != IntPtr.Zero)
                    P_Invoke.WlanFreeMemory(ppInterfaceList);

                //close handle
                P_Invoke.WlanCloseHandle(handle, IntPtr.Zero);

                return netList;
            }
            return netList;
        }



    }
}